import { CSS3DObject, CSS3DSprite, CSS3DRenderer } from "three/examples/jsm/renderers/CSS3DRenderer"
import { uuid } from "../utils"
import {
  Vector3,
  Euler,
} from "three";
export class Label3d {
  constructor({ scene, camera, time, sizes, canvas }) {
    this.scene = scene
    this.camera = camera
    this.time = time
    this.sizes = sizes
    this.canvas = canvas
    this.parent = null
    this.labels = new Set()
    this.lastCameraPosition = new Vector3()
    this.lastCameraRotation = new Euler()
    
    let { width, height } = this.sizes
    let css3dRender = new CSS3DRenderer()
    css3dRender.setSize(width, height)
    css3dRender.domElement.style.position = "absolute"
    css3dRender.domElement.style.left = "0px"
    css3dRender.domElement.style.top = "0px"
    css3dRender.domElement.style.pointerEvents = "none"
    css3dRender.domElement.className = "label3d-" + uuid()
    this.canvas.parentNode.appendChild(css3dRender.domElement)
    this.css3dRender = css3dRender
    
    // 优化：添加防抖处理
    this.resize = this.resize.bind(this)
    this.sizes.on("resize", () => {
      requestAnimationFrame(this.resize)
    })
    
    // 记录相机状态，用于优化渲染
    this.updateCameraState()
  }
  
  // 记录相机状态
  updateCameraState() {
    this.lastCameraPosition.copy(this.camera.instance.position)
    this.lastCameraRotation.copy(this.camera.instance.rotation)
  }
  
  // 优化：检查相机是否移动
  hasCameraMoved() {
    return !this.lastCameraPosition.equals(this.camera.instance.position) || 
           !this.lastCameraRotation.equals(this.camera.instance.rotation)
  }

  /**
   * 创建3d标签
   */
  create(name = "", className = "", isSprite = false) {
    let tag = document.createElement("div")
    tag.innerHTML = name
    tag.className = className
    tag.style.visibility = "hidden"
    tag.style.position = "absolute"
    
    // 优化：添加3D渲染优化样式
    tag.style.transformStyle = "preserve-3d"
    tag.style.backfaceVisibility = "hidden"
    tag.style.willChange = "transform, opacity"
    tag.style.transition = "opacity 0.1s ease"
    
    // 如果className不存在，用以下样式
    if (!className) {
      tag.style.padding = "10px"
      tag.style.color = "#fff"
      tag.style.fontSize = "12px"
      tag.style.textAlign = "center"
      tag.style.background = "rgba(0,0,0,0.6)"
      tag.style.borderRadius = "4px"
      tag.style.pointerEvents = "none"
    }
    
    let label = null
    if (!isSprite) {
      label = new CSS3DObject(tag)
    } else {
      label = new CSS3DSprite(tag)
    }
    
    // 存储标签引用以便管理
    this.labels.add(label)

    /**
     * 标签初始化并显示
     */
    label.init = (name, point) => {
      label.element.innerHTML = name
      label.element.style.visibility = "visible"
      label.position.copy(point)
    }
    
    /**
     * 隐藏
     */
    label.hide = () => {
      label.element.style.visibility = "hidden"
    }
    
    /**
     * 显示
     */
    label.show = () => {
      label.element.style.visibility = "visible"
    }
    
    label.setParent = (parent) => {
      this.parent = parent
      parent.add(label)
    }
    
    label.remove = () => {
      this.parent.remove(label)
      this.labels.delete(label)
    }
    
    return label
  }
  
  /**
   * 设置label的样式
   */
  setLabelStyle(label, scale = 0.1, axis = "x", pointerEvents = "none") {
    label.element.style.pointerEvents = pointerEvents
    label.scale.set(scale, scale, scale)
    label.rotation[axis] = Math.PI / 2
  }
  
  /**
   * 优化：仅在必要时更新渲染
   */
  update() {
    // 只有相机移动时才重新渲染CSS3D元素
    if (this.hasCameraMoved()) {
      this.css3dRender.render(this.scene, this.camera.instance)
      this.updateCameraState()
    }
  }
  
  destroy() {
    if (this.css3dRender) {
      let domElement = this.css3dRender.domElement
      domElement.parentNode.removeChild(domElement)
    }
    
    // 清理所有标签
    this.labels.clear()
  }
  
  resize() {
    let { width, height } = this.sizes
    this.css3dRender.setSize(width, height)
  }
}